#!/usr/bin/env python3
"""
震动键盘系统演示脚本

演示系统的主要功能，包括：
- 震动模型模拟
- 信号处理
- 特征提取
- 键位识别
- 实时更新
"""

import sys
import numpy as np
import time
from pathlib import Path

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

from src.vibration_model import MultiModalVibration, DecayModel
from src.signal_processing import EndpointDetection, DTWAlgorithm
from src.feature_extraction import TimeDomainFeatures, FrequencyDomainFeatures
from src.key_recognition import KNNClassifier
from src.real_time_update import RealTimeUpdateSystem
from src.utils.config_manager import ConfigManager


def demo_vibration_model():
    """演示震动模型"""
    print("=== 震动模型演示 ===")
    
    # 创建多模态震动模型
    vibration_model = MultiModalVibration()
    
    # 模拟震动传播
    source_position = (0, 0)
    grid_size = (20, 20)
    
    print("模拟震动传播...")
    X, Y, amplitudes = vibration_model.simulate_multi_modal_propagation(
        1.0, source_position, grid_size
    )
    
    print(f"震动传播完成，网格大小: {X.shape}")
    print(f"最大振幅: {np.max(amplitudes):.4f}")
    print(f"最小振幅: {np.min(amplitudes):.4f}")
    
    # 测试衰减模型
    decay_model = DecayModel()
    distances = np.linspace(0, 5, 50)
    decayed_amplitudes = decay_model.calculate_amplitude(1.0, distances, 0.1)
    
    print(f"衰减模型测试完成，距离范围: {distances[0]:.1f} - {distances[-1]:.1f}")
    print(f"衰减后振幅范围: {decayed_amplitudes[0]:.4f} - {decayed_amplitudes[-1]:.4f}")
    
    print()


def demo_signal_processing():
    """演示信号处理"""
    print("=== 信号处理演示 ===")
    
    # 生成测试信号
    sample_rate = 100
    duration = 2.0
    t = np.linspace(0, duration, int(sample_rate * duration))
    
    # 创建包含敲击的信号
    signal_data = np.zeros_like(t)
    # 在中间添加敲击信号
    start_idx = int(0.5 * sample_rate)
    end_idx = int(0.7 * sample_rate)
    signal_data[start_idx:end_idx] = np.sin(2 * np.pi * 50 * t[start_idx:end_idx]) * np.exp(-10 * (t[start_idx:end_idx] - t[start_idx]))
    
    # 添加噪声
    signal_data += np.random.normal(0, 0.1, len(signal_data))
    
    print(f"生成测试信号，长度: {len(signal_data)} 采样点")
    
    # 端点检测
    endpoint_detector = EndpointDetection()
    start_sample, end_sample = endpoint_detector.detect_endpoints(signal_data)
    
    print(f"端点检测结果: 起始点 {start_sample}, 结束点 {end_sample}")
    print(f"有效信号长度: {end_sample - start_sample} 采样点")
    
    # DTW算法测试
    dtw_algorithm = DTWAlgorithm()
    
    # 生成两个相似的时间序列
    t_short = np.linspace(0, 1, 50)
    sequence_x = np.sin(2 * np.pi * 5 * t_short)
    sequence_y = np.sin(2 * np.pi * 5 * (t_short + 0.1))  # 稍微偏移
    
    distance, path = dtw_algorithm.compute_dtw_distance(sequence_x, sequence_y)
    similarity = dtw_algorithm.compute_similarity(sequence_x, sequence_y)
    
    print(f"DTW距离: {distance:.4f}")
    print(f"相似度: {similarity:.4f}")
    
    print()


def demo_feature_extraction():
    """演示特征提取"""
    print("=== 特征提取演示 ===")
    
    # 生成测试信号
    t = np.linspace(0, 1, 1000)
    signal_data = np.sin(2 * np.pi * 10 * t) + 0.5 * np.sin(2 * np.pi * 20 * t)
    signal_data += np.random.normal(0, 0.1, len(signal_data))
    
    print(f"生成测试信号，长度: {len(signal_data)} 采样点")
    
    # 时域特征提取
    time_features = TimeDomainFeatures()
    time_feats = time_features.extract_features(signal_data)
    
    print("时域特征:")
    for feature_name, value in time_feats.items():
        print(f"  {feature_name}: {value:.4f}")
    
    # 频域特征提取
    freq_features = FrequencyDomainFeatures()
    freq_feats = freq_features.extract_features(signal_data)
    
    print("频域特征:")
    for feature_name, value in freq_feats.items():
        if isinstance(value, np.ndarray):
            print(f"  {feature_name}: 数组长度 {len(value)}")
        else:
            print(f"  {feature_name}: {value:.4f}")
    
    print()


def demo_key_recognition():
    """演示键位识别"""
    print("=== 键位识别演示 ===")
    
    # 创建分类器
    classifier = KNNClassifier(n_neighbors=3)
    
    # 生成训练数据
    np.random.seed(42)
    n_samples = 60
    n_features = 10
    
    # 为3个类别生成数据
    X_train = []
    y_train = []
    
    for i in range(3):
        # 每个类别有不同的特征分布
        class_data = np.random.normal(i, 1, (n_samples, n_features))
        X_train.extend(class_data)
        y_train.extend([f'key_{i}'] * n_samples)
    
    X_train = np.array(X_train)
    y_train = np.array(y_train)
    
    print(f"训练数据: {X_train.shape[0]} 样本, {X_train.shape[1]} 特征")
    print(f"类别: {set(y_train)}")
    
    # 训练分类器
    classifier.fit(X_train, y_train)
    print("分类器训练完成")
    
    # 生成测试数据
    X_test = np.random.normal(1, 1, (5, n_features))
    
    # 预测
    predictions = classifier.predict(X_test)
    probabilities = classifier.predict_proba(X_test)
    candidates = classifier.predict_with_confidence(X_test, max_candidates=2)
    
    print("预测结果:")
    for i, (pred, prob, cand) in enumerate(zip(predictions, probabilities, candidates)):
        print(f"  样本 {i+1}: 预测={pred}, 置信度={prob.max():.3f}")
        print(f"    候选: {cand}")
    
    # 评估性能
    y_test = np.array(['key_1'] * 5)  # 假设真实标签
    evaluation = classifier.evaluate(X_test, y_test)
    
    print(f"评估结果: 准确率 = {evaluation['accuracy']:.4f}")
    
    print()


def demo_real_time_update():
    """演示实时更新"""
    print("=== 实时更新演示 ===")
    
    # 创建实时更新系统
    update_system = RealTimeUpdateSystem(
        max_samples_per_key=50,
        update_threshold=0.7,
        outlier_detection=True
    )
    
    # 创建分类器
    classifier = KNNClassifier(n_neighbors=3)
    
    # 生成初始训练数据
    np.random.seed(42)
    X_initial = np.random.normal(0, 1, (30, 5))
    y_initial = np.array(['a'] * 15 + ['b'] * 15)
    
    classifier.fit(X_initial, y_initial)
    print(f"初始训练完成，样本数: {len(X_initial)}")
    
    # 模拟实时更新
    print("开始实时更新...")
    for i in range(10):
        # 生成新样本
        new_feature = np.random.normal(0, 1, (1, 5))
        correct_key = 'a' if i % 2 == 0 else 'b'
        
        # 预测
        prediction = classifier.predict(new_feature)[0]
        confidence = classifier.predict_proba(new_feature).max()
        
        print(f"  更新 {i+1}: 真实={correct_key}, 预测={prediction}, 置信度={confidence:.3f}")
        
        # 更新系统
        update_system.update_sample(
            classifier, new_feature.flatten(), correct_key, prediction, confidence
        )
    
    # 获取统计信息
    stats = update_system.get_sample_statistics()
    print("样本统计:")
    for key, info in stats.items():
        print(f"  {key}: {info['count']} 样本")
    
    print()


def demo_full_pipeline():
    """演示完整处理流程"""
    print("=== 完整处理流程演示 ===")
    
    # 1. 生成震动信号
    sample_rate = 100
    duration = 1.0
    t = np.linspace(0, duration, int(sample_rate * duration))
    signal_data = np.sin(2 * np.pi * 10 * t) * np.exp(-5 * t)
    signal_data += np.random.normal(0, 0.1, len(signal_data))
    
    print(f"1. 生成震动信号，长度: {len(signal_data)} 采样点")
    
    # 2. 端点检测
    endpoint_detector = EndpointDetection()
    start_sample, end_sample = endpoint_detector.detect_endpoints(signal_data)
    valid_signal = signal_data[start_sample:end_sample]
    
    print(f"2. 端点检测完成，有效信号长度: {len(valid_signal)} 采样点")
    
    # 3. 特征提取
    time_features = TimeDomainFeatures()
    freq_features = FrequencyDomainFeatures()
    
    time_feats = time_features.extract_features(valid_signal)
    freq_feats = freq_features.extract_features(valid_signal)
    
    # 组合特征
    combined_features = np.array(list(time_feats.values()) + [np.mean(v) if isinstance(v, np.ndarray) else v for v in freq_feats.values()])
    
    print(f"3. 特征提取完成，特征维度: {len(combined_features)}")
    
    # 4. 键位识别
    classifier = KNNClassifier(n_neighbors=3)
    
    # 训练数据
    X_train = np.random.normal(0, 1, (60, len(combined_features)))
    y_train = np.array(['a'] * 20 + ['b'] * 20 + ['c'] * 20)
    classifier.fit(X_train, y_train)
    
    # 预测
    prediction = classifier.predict(combined_features.reshape(1, -1))[0]
    confidence = classifier.predict_proba(combined_features.reshape(1, -1)).max()
    
    print(f"4. 键位识别完成，预测: {prediction}, 置信度: {confidence:.3f}")
    
    # 5. 实时更新
    update_system = RealTimeUpdateSystem()
    update_system.update_sample(classifier, combined_features, 'a', prediction, confidence)
    
    print("5. 实时更新完成")
    
    print("完整处理流程演示结束！")


def main():
    """主函数"""
    print("震动键盘系统演示")
    print("=" * 50)
    
    try:
        # 演示各个模块
        demo_vibration_model()
        demo_signal_processing()
        demo_feature_extraction()
        demo_key_recognition()
        demo_real_time_update()
        demo_full_pipeline()
        
        print("所有演示完成！")
        
    except Exception as e:
        print(f"演示过程中出现错误: {e}")
        import traceback
        traceback.print_exc()


if __name__ == "__main__":
    main() 